/* eslint-disable */
import context from '@/main.js'
import store from '@/vuex/index.js'
import dates from '@/util/dates.js'
import crypto from 'crypto'
const defaultSettings = require('../settings.js')
let proxyApi = process.env.VUE_APP_BASE_API
const utils = {
  // 回调转异步
  promisify(func, ctx) {
    // 返回一个新的function
    return function() {
      // 初始化this作用域
      var ctx = ctx || this
      // 新方法返回的promise
      return new Promise((resolve, reject) => {
        // 调用原来的非promise方法func，绑定作用域，传参，以及callback（callback为func的最后一个参数）
        func.call(ctx, ...arguments, function() {
          // 将回调函数中的的第一个参数error单独取出
          var args = Array.prototype.map.call(arguments, item => item)
          var err = args.shift()
          // 判断是否有error
          if (err) {
            reject(err)
          } else {
            // 没有error则将后续参数resolve出来
            args = args.length > 1 ? args : args[0]
            resolve(args)
          }
        })
      })
    }
  },
  // 克隆JSON对象
  jsonClone(obj) {
    const str = obj.constructor === String ? obj : JSON.stringify(obj)
    return JSON.parse(str)
  },
  // 驼峰转下划线
  toUnderlineName(oriName) {
    return oriName.replace(/([A-Z])/g, '_$1').toLowerCase()
  },
  // 下划线转驼峰
  toHump(name) {
    return name.replace(/\_(\w)/g, (all, letter) => letter.toUpperCase())
  },
  // md5加密
  md5(str) {
    const md5 = crypto.createHash('md5')
    md5.update(str)
    return md5.digest('hex')
  },
  // 随机编码（指定长度）
  randomCode(len) {
    return this.md5(new Date().toString() + Math.random().toString()).substring(0, len)
  },
  uuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
      const r = (Math.random() * 16) | 0
      const v = c == 'x' ? r : (r & 0x3) | 0x8
      return v.toString(16)
    })
  },
  sleep(ms) {
    const _sleep = ms => new Promise((r, j) => setTimeout(r, ms))
    ;(async () => {
      await _sleep(ms)
    })()
  },
  /**
   * 树形结构查找
   * @param {Array} src:查找的源对象数组
   * @param {Function} cb:回调函数，回调的参数为源对象
   * @param {String} childName:儿子节点名称，默认children
   */
  findTreeNode(src, cb, childName = 'children') {
    const foundResult = []
    src.forEach(item => {
      if (cb(item)) {
        foundResult.push(item)
      }
      item.children && foundResult.push(...this.findTreeNode(item[childName], cb))
    })
    return foundResult
  },

  /** 打开菜单路由
   * @param routeName 对应菜单里面的 route 或者name
   */
  openMenu(routeName, params = {}, autoQuery = true) { //autoQuery自动在页面加载时根据参数进行查询
    const menus = store.getters.menus
    const foundMenus = this.findTreeNode(menus, m => m.route == routeName || m.name == routeName || (m.properties && m.properties.url && m.properties.url.indexOf(routeName) != -1 ) ) || []
    if (foundMenus.length == 0) {
      throw new Error('未找到路由名称')
    }
    if (foundMenus.length < 0) {
      throw new Error('找到多条路由名称')
    }

    let foundMenusOne = foundMenus[0]
    let url = foundMenusOne.properties && foundMenusOne.properties.url ? foundMenusOne.properties.url : ''
    // html链接
    if (url.indexOf('.html') != -1) {
      let to = url.replace('.html', '')
      context.$router.replace({path: to, query: params}, () => {
      })
      return
    }else if (url.indexOf('.vue') != -1) {// vue 页面
      let name = url.replace('.vue', '')
      context.$router.replace({path: name, query: params}, () => {
      })
      return
    }




    params['autoQuery'] = autoQuery
    // 注意：跳转过去的页面不能有报错，容易导致页面空白数据加载不出来
    if ( foundMenusOne.name) {
      context.$router.replace({ name: foundMenusOne.name, params }).catch(err => {console.error('openMenu', err)})
    } else if(foundMenusOne.route) {
      context.$router.replace({ name: foundMenusOne.route, params }).catch(err => {console.error('openMenu', err)})
    } else {
      context.$router.push({ path: foundMenusOne.path, params })
    }
  },
  /**
   * 打开自定义的窗口
   * @param {Object} options : {routeName: '全局唯一', url: '/sys/wi/index.vue', para: {pk: '1212121212'}}
   */
  openForm(options) {
    const routeName = options.routeName
    const url = options.url
    if (!routeName || !url) {
      throw new Error('请指定路由名称和URL')
    }
    const routes = context.$router.options.routes
    const foundRoutes= this.findTreeNode(routes, r => r.name == routeName) || []
    let route = {}
    if (foundRoutes.length == 0) {
      route = context.$router.options.routes[1]
      route.children = []
      route.children.push({
        path: `${routeName}/`,
        name: routeName,
        component: (resolves) => require([`@/views/${url}`], resolve),
        meta: {
          requireAuth: true,
          title: options.title || '页面'
        }
      })
      context.$router.addRoutes([route])
    } else {
      route = foundRoutes[0]
    }
    context.$router.push({ name: routeName, params: options.para })
  },
  /* 给出行数据和配置，生成树形的数据结构
   *  data:数据源，
   *  config 可配置根节点（不配置，默认第一条），key字段名，label字段名,示例：
   * { rootNode: {id:1, parentId:0, name:'根节点' }, keyFieldName: 'id', parentFieldName: 'parentId', labelFieldName: 'name'}
   */
  convertToTree(data, config) {
    const tree = []
    let rootNode = {}
    // 未指定根节点信息，读取第一条数据作为根节点
    if (config.rootNode) {
      rootNode = config.rootNode
      rootNode.label = rootNode.label || rootNode[config.labelFieldName]
    } else {
      if (data.length < 1) {
        rootNode[config.keyFieldName] = -1
        rootNode.label = '无数据'
      } else {
        rootNode[config.keyFieldName] = data[0][config.keyFieldName]
        rootNode.label = data[0][config.labelFieldName]
      }
    }

    if (data.length > 0) {
      let currentUser = this.getCurrentUser()
      rootNode.children = this._getTreeChildren(rootNode, data, config, currentUser, 0)
    }

    tree.push(rootNode)
    return tree
  },
  _getTreeChildren(parentNode, data, config, currentUser, level) {
    level += 1
    const children = []
    const childArr = data.filter(item => {
      return item[config.parentFieldName] == parentNode[config.keyFieldName]
    })
    if (childArr.length < 1) return null
    childArr.forEach((currentValue, index, arr) => {
      const node = {}
      node[config.keyFieldName] = currentValue[config.keyFieldName]
      node.label = currentValue[config.labelFieldName]
      node.meta = currentValue
      node.level = level
      if (node.meta.isHidden) {
        return
      }
      if (node.meta.isAdminMenu && currentUser && !currentUser.admin) {
        return
      }
      node.children = this._getTreeChildren(currentValue, data, config, currentUser, level)
      children.push(node)
    })
    return children
  },
  // == end ==
  /**
   * 获取字典标签
   * @param {String} value
   * @param {String} type
   * @param {*} defaultValue
   */
  getDictLabel(value, type, defaultValue, showColor = true) {
    if (value === undefined || value === null || value === '' || type === undefined || type === null || type === '') {
      return defaultValue
    }

    let dictDataList = store.getters.dictDataMap.get(type)
    // if (dictDataList && type == 'common_yes_no') {
    //   dictDataList.forEach(d => d.value = Boolean(d.value))
    // }
    for (const index in dictDataList) {
      let d = dictDataList[index]
      if (d.value == value || d.label == value) {
        let label = d.label
        return showColor ? `<span style="background-color: ${d.color ? d.color : '#184dde'}; color: #fff;padding: 3px;font-size: 12px;">${label}</span>` : label
      }
    }
    return defaultValue
  },
  // == end ==
  /**
   * 获取布尔类型标签
   * @param {String} value
   * @param {String} type
   * @param {*} defaultValue
   */
  getBooleanLabel(value, yesLabel,noLabel,withMarginLeft) {
    if ([true,'true','1',1].includes(value)) {
      return `<span style="background-color: #0142b2; color: #fff;padding: 3px;font-size: 12px;margin-left: ${withMarginLeft ? '5px' : '0px'}">${yesLabel}</span>`
    }
    return `<span style="background-color: #F56C6C; color: #fff;padding: 3px;font-size: 12px;;margin-left: ${withMarginLeft ? '5px' : '0px'}">${noLabel}</span>`
  },
  getDictDataList(type, that) {
    let dict = store.getters.dictDataMap.get(type)
    if (!dict) return []
    return dict.sort((o1, o2) => {
      const sort1 = global.strings.defaultIfBlank(o1.sort, 999)
      const sort2 = global.strings.defaultIfBlank(o2.sort, 999)
      return sort1 - sort2
    })
  },
  now() {
    return new Date().format('yyyy/MM/dd hh:mm:ss')
  },
  getStringParam(key, defaultValue) {
    let value = store.getters.parameterMap.get(key)
    return value ? value : defaultValue
  },
  getBooleanParam(key, defaultValue = false) {
    let value = store.getters.parameterMap.get(key)
    if (strings.isBlank(value)) {
      return defaultValue
    }
    return value == '1'
  },
  convertToBoolean(value) {
    if (value == '1') {
      return true
    }
    if (value == '0') {
      return false
    }
    return value
  },
  paramsEquals(params1, params2) {
    let equality = true
    Object.keys(params1).forEach((key) => {
      if (Object.prototype.hasOwnProperty.call(params1, key)) {
        if (params1[key] != params2[key]) {
          equality = false
        }
      }
    })
    return equality
  },
  isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item)
  },
  mergeDeep(target, ...sources) {
    if (!sources.length) return target

    const source = sources.shift()
    if (this.isObject(target) && this.isObject(source)) {
      for (const key in source) {
        if (!target[key]) {
          Object.assign(target, {
            [key]: source[key]
          })
          continue
        }

        if (Array.isArray(source[key])) {
          if (this.isObject(target[key])) {
            Object.assign(target, {
              [key]: source[key]
            })
          } else {
            for (let i = 0; i < source[key].length; i++) {
              let sourceValueType = typeof source[key][i]
              if (['string', 'number'].includes(sourceValueType)) {
                target[key][i] = source[key][i]
              } else {
                this.mergeDeep(target[key][i], source[key][i])
              }
            }
          }
          continue
        }

        if (this.isObject(source[key])) {
          if (Array.isArray(target[key])) {
            Object.assign(target, {
              [key]: source[key]
            })
            continue
          }
          this.mergeDeep(target[key], source[key])
        }
      }
    }
    return this.mergeDeep(target, ...sources)
  },
  //字符串转换成json对象，单层
  str2json(jsonStr){
    if (strings.isBlank(jsonStr)) return null
    return JSON.parse(jsonStr);
  },

  //json对象转换成json字符串
  json2str(jsonOb){
    return JSON.stringify(jsonOb);
  },

  //获取登录用户信息
  getCurrentUser() {
    return this.getUser()
  },
  //获取当前所设置的工位
  /**
   * @Description：${description}
   * @Date 2023-10-23
   */
  getCurrentWarehouse() {
    return store.getters.currentWarehouse
  },
  //获取数据字典
  getDictDataMap() {
    return store.getters.dictDataMap
  },
  //获取当前查询条件和耗材数据
  getCurrentMatrs() {
    return store.getters.currentMatrs
  },

  /**
   * @Description：下载 static/download目录下的文件
   * @param fileType : 文件后缀
   * @param fileName : 文件名，不包含后缀
   */
  downloadStatic(fileType,fileName) {
    window.location.href ='/api/sys/file/download/'+fileType+'/'+fileName
  },

  /**
   * @Description：下载文件 根据绝对路径
   * @param fileAbPath : 文件绝对路径
   * @param fileName : 文件名
   */
  downloadAbfile(fileAbPath,fileName) {
    window.location.href = ` /api/tool/downloadAbfile?fileAbPath=${fileAbPath}&fileName=${fileName}`
  },

  /**
   * @Description：下载文件
   * @param fileId : 文件id
   * @param fileName : 文件名
   */
  downloadByFile(file) {
    // window.open(file.url)


    location.href = this.getBaseUrlFull() + `/sys/file/downloadById?fileId=${file.id}`
    // window.open(`/api/sys/file/downloadById?fileId=${file.id}`)
  },


  /**刷新上级网格和本页面表单
   * 如果上级dataview 包含amount等动态字段
   * 扫描添加后，明细删除后
   * eg: this.utils.refreshRefs(this)
   */
  refreshRefs(that) {
    //刷新本页面表单
    that.propParent.ocRefreshCurrentRow()
    // //刷新上级网格明细
    // that.propParent.ocRefresh()
  },


  /**根据路由参数打开对应行
   * 不做操作 dataView ==null || that.$route.params.id == null
   * @param dataView
   * @param that
   */
  viewRow(dataView, that) {
    setTimeout(() => {
      utils._viewRow(dataView, that)
    }, 500)
  },
  async _viewRow(dataView, that) {
    if (!dataView) return
    if (!that.$route.params.id) return
    let wrapper = global.queryWrappers.newWrapper().eq('id', that.$route.params.id)
    that[dataView].setQueryWrapper(wrapper, false)
    await that[dataView].fetchData()
    setTimeout(() => {
      that[dataView].viewRow(that.$route.params.id)
    }, 500)
  },

  /**报表和数据视图导出功能
   * @type：类型  report dataview
   * @code 唯一标识 报表标识或者数据视图标识
   * @queryString 筛选条件
   * @orderBy 排序条件
   * @exportFooterSignArr  导出底部签名栏，数组
   * @exportFooterSumArr  导出底部合计区，数组
   */
  export(type, code, queryString, orderBy, exportFooterSignArr, exportFooterSumArr) {
    let param ={
      type: type,
      code: code,
      queryString: queryString,
      orderBy: orderBy,
      exportFooterSignArrStr: exportFooterSignArr ? utils.json2str(exportFooterSignArr) : null,
      exportFooterSumArrStr: exportFooterSumArr ? utils.json2str(exportFooterSumArr) : null,
    }
    global.utilVue.loadShow(true)
    global.$ajax.post('/tool/export', param).then(resp => {
      if (resp.code == 0) {
        global.utils.downloadrRes(resp.data)
      }
      setTimeout(() => {
        global.utilVue.loadHide()
      }, 500)
    })
  },
  /**
   * @Description：下载 res目录下的文件
   * @param filePathName : 文件名，不包含res
   */
  downloadrRes(filePathName) {
    let download =  location.origin+'/api/res/'+ filePathName
    window.location.href = download
  },
  /**
   * @Description：下载 res目录下的文件
   * @param filePathName : 文件名，包含/res
   */
  downloadNoRes(filePathName) {
    let download =  location.origin+'/api/'+ filePathName
    window.open(download, "_blank");
  },
  /**
   * @Description：下载 res目录下的文件(如jpg,txt,json等，浏览器会直接打开，不提供下载，此方法可以进行下载)
   * @param filePathName : 文件名，不包含res
   */
  downloadContextRes(filePathName) {
    let download =  location.origin+'/api/res/'+ filePathName
    global.$ajax.get(download).then(resp => {
      let result = JSON.stringify(resp.data)
      var datastr = `data:text/json;charset=utf-8,${result}`
      var link = document.createElement("a")
      link.setAttribute("href", datastr)
      link.setAttribute("download", filePathName.substring(filePathName.lastIndexOf('/') + 1))
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    })
  },
  /**
   * @Description： 获取供应商平台toekn
   * @return  token
   */
  async getMscmToken() {
    let token = null
    await global.$ajax.get('/mscm/getAccessToken').then(resp => {
      if ( resp.code == 0 ){
        token = resp.data
      }
    })
    return token
  },
  parseRules(rules) {
    if (!rules || rules.length < 1) return {}
    const obj = {}
    Object.keys(rules).forEach((objKey) => {
      const tmp = []
      rules[objKey].forEach((item) => {
        try {
          if (item.constructor !== String) {
            tmp.push(item)
          } else {
            tmp.push(JSON.parse(item))
          }
        } catch(e) {
          console.error('解析规则失败，原因如下')
          console.error(e)
        }
      })
      obj[objKey] = tmp
    })
    return obj
  },
  //获得文件类型
  getFileType(fileName) {
    return  fileName.substring(fileName.lastIndexOf('.')+1);
  },
  //判断是否是图片
  isImg(fileName) {
    if(!fileName ) return false
    let typeName=utils.getFileType(fileName);
    return 'jpeg,jpg,png,icon'.indexOf(typeName) != -1
  },

  //Html转换为TextArea文本
  htmlToText(str){
    if (str == null) {
      return "";
    }else if (str.length == 0) {
      return "";
    }
    return str.replace(/(\r\n|\n|\r)/gm, "<br />");;
  },

  //TextArea文本转换为Html:写入数据库时使用
  text2Html(str){
    if (str == null) {
      return "";
    }else if (str.length == 0) {
      return "";
    }
    return str.replace(/<br>/g,"\n");;
  },


  //获取流程校验参数，仅用于子页面
  getCheckFlowParam(that) {
    let propObject = null
    if (that.haveFlowField) {
      propObject = that
    }
    if (that.propParent && that.propParent.haveFlowField) {
      propObject = that.propParent
    }

    if (!propObject) {
      return {}
    }
    let param = {
      checkFlowCode: propObject.propFlowKey,
      checkFlowBusTable: propObject.baseTable,
      checkFlowBusId: propObject.viewFormData? propObject.viewFormData[propObject.primaryKey] : null ,
      checkFlowBusFlowStatus: propObject.viewFormData? propObject.viewFormData.flowStatus : null ,
      flowNodes: propObject.flowNodes
    }
    if (global.strings.isBlank(param.checkFlowBusFlowStatus)) param.checkFlowBusFlowStatus = 'start'
    return param
  },

  //追加拦截器需要使用的参数
  appendParamForInterceptor(that, type, oldParam, param) {
    if (type == 'dataviewsave' ) { //数据视图保存
      //数据校验参数
      oldParam.interceptorOpTable = that.baseTable
      oldParam.interceptorOpPkName = that.primaryKey
      oldParam.interceptorOpPkId = oldParam[that.primaryKey]
      oldParam.interceptorOpUpdateLast = oldParam.gmtModified

      //流程校验参数
      if (that.propCheckFlowParam) { //子页面dataview
        //流程标识
        oldParam.checkFlowCode = that.propCheckFlowParam.checkFlowCode
        //业务主表名称
        oldParam.checkFlowBusTable = that.propCheckFlowParam.checkFlowBusTable
        //业务主键
        oldParam.checkFlowBusId = that.propCheckFlowParam.checkFlowBusId
        //允许操作的流程状态，多个,号分割
        let checkFlowStatusPass = []
        if (that.btnNodeMap && that.btnNodeMap.showViewButtonAdd && that.btnNodeMap.showViewButtonAdd.length > 0) checkFlowStatusPass = that.btnNodeMap.showViewButtonAdd
        oldParam.checkFlowStatusPass = checkFlowStatusPass.join(',')
      }else if(that.haveFlowField) {//有流程字段的数据视图
        //流程标识
        oldParam.checkFlowCode = that.propFlowKey
        //业务主表名称
        oldParam.checkFlowBusTable = that.baseTable
        //业务主键
        oldParam.checkFlowBusId = that.currentRow ? that.currentRow[that.primaryKey] : null
        //允许操作的流程状态，多个,号分割
        let flowNodes = that.flowNodes
        let checkFlowStatusPass = []
        if (flowNodes) {
          //显示保存按钮的流程节点，允许操作
          flowNodes.filter(node1 => node1.flagShowVfbSave).forEach(node2 => {
            checkFlowStatusPass.push(node2.value)
          })
        }
        oldParam.checkFlowStatusPass = checkFlowStatusPass.join(',')
      }

      oldParam.checkFlowOpTypeName = '保存'
    }else if (type == 'dataviewflow') { //数据视图流程操作
      oldParam.interceptorOpTable = that.baseTable
      oldParam.interceptorOpPkName = that.primaryKey
      oldParam.interceptorOpPkId = that.viewFormData[that.primaryKey]
      oldParam.interceptorOpUpdateLast = that.viewFormData.gmtModified

      //流程校验参数
      //流程标识
      oldParam.checkFlowCode = that.propFlowKey
      //业务主表名称
      oldParam.checkFlowBusTable = that.baseTable
      //业务主键
      oldParam.checkFlowBusId = that.viewFormData[that.primaryKey]
      //允许操作的流程状态，多个,号分割
      let flowNodes = that.flowNodes
      let checkFlowStatusPass = []
      if (flowNodes) {
        //操作按钮显示值符合条件的流程节点，即为可操作的流程
        flowNodes.filter(node1 => node1.value == param.valueIf).forEach(node2 => {
          checkFlowStatusPass.push(node2.value)
        })
      }
      oldParam.checkFlowStatusPass = checkFlowStatusPass.join(',')
      oldParam.checkFlowOpTypeName = '流程'+param.title
    } else if (type == 'dataviewdelete') { //数据视图删除操作
      oldParam.interceptorOpTable = that.baseTable
      oldParam.interceptorOpPkName = that.primaryKey
      oldParam.interceptorOpPkId = oldParam.ids
      oldParam.interceptorOpViewName = that.viewName

      let gmtModifiedArr = []
      let buskeyArr = []
      param.forEach((item) => {
        gmtModifiedArr.push(item.gmtModified)
        buskeyArr.push(item.busKey)
      })
      oldParam.interceptorOpUpdateLastArr = gmtModifiedArr
      oldParam.interceptorOpBusKeyArr = buskeyArr

      //流程校验参数
      if (that.propCheckFlowParam) { //子页面dataview
        //流程标识
        oldParam.checkFlowCode = that.propCheckFlowParam.checkFlowCode
        //业务主表名称
        oldParam.checkFlowBusTable = that.propCheckFlowParam.checkFlowBusTable
        //业务主键
        oldParam.checkFlowBusId = that.propCheckFlowParam.checkFlowBusId
        //允许操作的流程状态，多个,号分割
        let checkFlowStatusPass = []
        if (that.btnNodeMap && that.btnNodeMap.showViewButtonDelete && that.btnNodeMap.showViewButtonDelete.length > 0) checkFlowStatusPass = that.btnNodeMap.showViewButtonDelete

        oldParam.checkFlowStatusPass = checkFlowStatusPass.join(',')
      }else if(that.haveFlowField) {//有流程字段的数据视图
        //流程标识
        oldParam.checkFlowCode = that.propFlowKey
        //业务主表名称
        oldParam.checkFlowBusTable = that.baseTable
        //业务主键
        oldParam.checkFlowBusIds = oldParam.ids
        //允许操作的流程状态，多个,号分割
        let flowNodes = that.flowNodes
        let checkFlowStatusPass = []
        if (flowNodes) {
          //显示删除按钮的流程节点，允许操作
          flowNodes.filter(node1 => node1.flagShowVfbDelete || node1.flagShowVbDelete).forEach(node2 => {
            checkFlowStatusPass.push(node2.value)
          })
        }
        oldParam.checkFlowStatusPass = checkFlowStatusPass.join(',')
      }
      oldParam.checkFlowOpTypeName = '删除'
    }
    oldParam.interceptorOpType = type
    return oldParam
  },

  //主页加载后执行，有需要可进行扩展
  afterHomeLoad(that) {
    this.getDeptBudget(that)
  },

  //获取用户可使用的科室列表
  getUserDeptList() {
    if (!store.getters.userDeptList) return []
    return store.getters.userDeptList
  },
  /**
   * 获取 部门名称根据id
   * @param {String} id
   */
  getUserDeptNameById(id) {
    if (!store.getters.userDeptList) return '未知'
    let userDeptList = store.getters.userDeptList
    for (const index in userDeptList) {
      let dept = userDeptList[index]
      if (dept.id == id ) {
        return dept.name
      }
    }
    return '未知'
  },
  /**
   *
   *根据id获取科室类型
   * @param id
   * @returns {string|string|*}
   */
  getDeptbusTypeById(id) {
    if (!store.getters.userDeptList) return '未知'
    let userDeptList = store.getters.userDeptList
    for (const index in userDeptList) {
      let dept = userDeptList[index]
      if (dept.id === id) {
        return dept.busType
      }
    }
    return '未知'
  },
  /**
   * 获取科室预算数据
   * 主页加载以及科室请领需求列表 after-load之后会加载
   */
  getDeptBudget(that, call) {
    //科室预算 区分全院预算和科室预算 此处先不显示
    return
    //获取科室预算信息
    global.$ajax.get(`/dept/budget/getBudgetForLoginUser` ).then((response) => {
      if(response.code == 0 ){
        that.$store.dispatch('setDeptBudget', response.data)
        if (call) call()
      }
    })
  },
  /**
   * 获取  科室预算并输入到html
   */
  getDeptBudgetMsg() {
    //科室预算 区分全院预算和科室预算 此处先不显示
    if (!store.getters.userDeptList) return ''
    let deptBudget = store.getters.deptBudget
    if (!deptBudget || !deptBudget.id) return ''
    let colorAmount ='green'
    let colorQty ='green'
    if (deptBudget.amountUseMonth > deptBudget.amount) colorAmount = 'red'
    if (deptBudget.qtyUseMonth > deptBudget.qty) colorQty = 'red'

    let msg = `
        <span style="color: ${colorAmount};display: inline-block;margin-right: 11px;font-weight: bold;margin-left: 11px">限额： <span >${deptBudget.amount}</span></span>
        <span style="color: ${colorAmount};display: inline-block;margin-right: 11px;font-weight: bold;">消耗额： <span >${deptBudget.amountUseMonth}</span></span>

        <span style="color: ${colorQty};display: inline-block;margin-right: 11px;font-weight: bold;">限量： <span >${deptBudget.qty}</span></span>
        <span style="color: ${colorQty};display: inline-block;margin-right: 11px;font-weight: bold;">消耗量： <span >${deptBudget.qtyUseMonth}</span></span>
    `
    return msg
  },

  //加载用户状态
  loadUserState(that, type, param, isBoolean, defaultIfNull) {
    let userState = that.$store.state.users.userState
    switch (type) {
      case 'workbenchWarehouse': //工作台仓库设置
        if (userState && userState &&  userState.workbenchWarehouse) {
          let warehouseFind = param.find(item => item.id == userState.workbenchWarehouse.id)
          if (!warehouseFind) return false
          that.setCurrent(warehouseFind)
          return true
        }
        break
      default:  //默认 type作为 key
        if (userState[type] == undefined && that.strings.isNotBlank(defaultIfNull) ) return defaultIfNull
        if (userState && userState &&  userState[type]) {
          if (isBoolean == true) {
            if (userState[type] == 'true' || userState[type] == '1') return true
            return false
          }
          return userState[type]
        }
    }
    return null
  },

  //加载用户状态- 标签打印
  loadPrinterLabelConfig(that, type, param, isBoolean, defaultIfNull) {
    let userState = that.$store.state.users.userState
    if (!userState) {
      return  {}
    }
    let printerLabelConfig = userState.printerLabelConfig
    if (printerLabelConfig) {
      printerLabelConfig = JSON.parse(printerLabelConfig)
    } else {
      printerLabelConfig = {}
    }
    return printerLabelConfig
  },
  /**
   *  更新用户操作状态
   *  @param type   操作类型
   *  @param param    操作类型的某一项的标识
   */
  updateUserState(type, param, that, isSend, hasLoad = false, callSuccess) {
    // switch (type) {
    //   case 'menu': //菜单改变后
    //     let visitedviews = store.getters.visitedviews
    //     param = visitedviews
    //     //菜单保留3个
    //     if (param && param.length > 3) param = param.slice(0,3)
    //     break
    // }
    // let userState = null
    // if (that) {
    //   userState = that.$store.state.users.userState
    // }
    // userState[type] = param
    // that.$store.dispatch('seUserState', userState)
  },

  //判断字符串是否是Json格式
  isJSON(str) {
    try {
      var obj=JSON.parse(str);
      if(typeof obj == 'object' && obj ){
        return true;
      }else{
        return false;
      }
    } catch(e) {
      console.log('error：'+str+'!!!'+e);
      return false;
    }
  },

  //获取数据视图配置  all 返回所有
  getDataviewConfigByKey(that,viewKey) {
    let dataviewMap = that.$store.state.users.dataviewMap
    if (!dataviewMap) {
      return null
    }
    if (viewKey == 'all') {
      return dataviewMap
    }
    return dataviewMap[viewKey]
  },

  //获取耗材类型： 从路由参数，默认为matr，参数名称 matrType
  getMtrBaseType(that) {
    if (!that && !that.propParameter && !that.propParam) return 'matr'
    if (that.propParam) { //子页面
      if (!that.propParam.matrBaseType || !['matr', 'reagent', 'drugs'].includes(that.propParam.matrBaseType)) return 'matr'
      return that.propParam.matrBaseType
    }
    if (that.propParameter) {
      //以下为菜单进入的一级页面
      let arr = that.propParameter.split("&")
      if (!arr || arr.length < 1) return 'matr'
      let params = {}
      for (var i = 0, l = arr.length; i < l; i++) {
        let a = arr[i].split("=")
        params[a[0]] = a[1]
      }
      if (!params.matrBaseType || !['matr', 'reagent', 'drugs'].includes(params.matrBaseType)) return 'matr'
      return params.matrBaseType
    }
    return 'matr'
  },

  //菜单是否展开 true:展开,false:折叠
  menuIsCollapse() {
    if (window.menuIsCollapse == undefined) return true
    return window.menuIsCollapse
  },

  /**
   * @Description： 根据目标字符串执行定时任务
   * @Author wyt
   * @Date 2023-09-21
   */
  runOnceByInvokeTarget(msg, invokeTarget, okFun) {
    global.utilMessage.confirm(`是否执行${msg}操作？`, () => {
      global.utilVue.loadShow(true)
      global.$ajax.get(`/sys/schedule_job/runOnceByInvokeTarget/${invokeTarget}`).then(resp => {
        global.utilVue.loadHide()
        if (resp.code == 0) {
          global.utilMessage.success(resp.msg)
          if (okFun) {
            okFun()
          }
        }
      })
    })
  },

  //获取url参数对象
  getObFromUrl(param) {
    if (!param) {
      return {}
    }
    let arr = param.split("&")
    if (!arr || arr.length < 1) {
      return {}
    }
    let params = {}
    for (var i = 0, l = arr.length; i < l; i++) {
      let a = arr[i].split("=")
      params[a[0]] = a[1]
    }
    return params
  },

  //追加参数到url后面
  appendToUrl(url, param) {
    if (!param || Object.keys(param).length == 0) {
      return url
    }
    let arr = []
    Object.keys(param).forEach(key => {
      arr.push(`${key}=${param[key]}`)
    })
    if (url.indexOf('?') == -1) {
      return url+='?' +  arr.join('&')
    }
    return url+=arr.join('&')
  },

  //是否是管理员
  isAdmin() {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'))
    return userInfo && userInfo.isAdmin
  },

  //是否是管理员
  getUser() {
    let user = JSON.parse(localStorage.getItem('userInfo'))
    if (user == null) {
      user = {}
    }
    return user
  },

  //是否是管理员
  getSpInfo() {
    let spInfo = JSON.parse(localStorage.getItem('spInfo'))
    if (spInfo == null) {
      spInfo = {}
    }
    return spInfo
  },

  //医院信息
  getHpInfo() {
    let hpInfo = JSON.parse(localStorage.getItem('hpInfo'))
    if (hpInfo == null) {
      hpInfo = {}
    }
    return hpInfo
  },
  // 对比两个对象的值是否完全相等 返回值 true/false
  isObjEq(a, b) {
    //取对象a和b的属性名
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);
    //判断属性名的length是否一致
    if (aProps.length != bProps.length) {
      return false;
    }
    //循环取出属性名，再判断属性值是否一致
    for (var i = 0; i < aProps.length; i++) {
      var propName = aProps[i];
      if (!(a[propName] instanceof Array) && a[propName] !== b[propName]) {
        return false;
      }
    }
    return true;
  },

  // 是否是供应商
  isSp() {
    let userInfo = global.utils.getCurrentUser()
    let deptType = userInfo ? userInfo.deptType : null
    return deptType == global.constCommon.deptType.supplier
  },

  // 是否是医院
  isHp() {
    let userInfo = global.utils.getCurrentUser()
    let deptType = userInfo ? userInfo.deptType : null
    return deptType == global.constCommon.deptType.hospital
  },

  // 是否是平台
  isPf() {
    let userInfo = global.utils.getCurrentUser()
    let deptType = userInfo ? userInfo.deptType : null
    return deptType == global.constCommon.deptType.platform
  },

  // 是否包含html标签
  hasHtml(htmlStr) {
    if (!htmlStr) {
      return  false
    }
    var reg = /<[^>]+>/g;
    return reg.test(htmlStr)
  },

  // 主题
  getTheme(theme) {
    if (!theme || global.constCommon.themeList.findIndex(item => item.value == theme) == -1) {
      return global.constCommon.themeList[0].value
    }
    return theme
  },
  toLogin() {
    context.$router.replace({path: defaultSettings.pathLogin}, () => {
    })
  },
  getToken() {
    return sessionStorage.getItem('X-Token')
  },
  getBaseUrlFull() {
    if (proxyApi.indexOf('http') != -1) {
      return '/api/'
    }
    return location.origin + proxyApi
  }
}
export default utils
